#include "humiture.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include <string.h>
#include <stdlib.h>
#include "mcp_server.h"
#include "application.h"

#define TAG "HumitureManager"

#define UART_PORT_NUM      UART_NUM_1        // 使用 UART0
#define TXD_PIN            GPIO_NUM_9      // 发送引脚
#define RXD_PIN            GPIO_NUM_10      // 接收引脚
#define BAUD_RATE          9600           // 波特率
#define BUF_SIZE           256             // 接收缓冲区大小
#define QUEUE_LENGTH 10

#define END_PATTERN '\n'  // 假设帧以\n结尾

QueueHandle_t uart_queue;

HumitureManager::HumitureManager()
{
    ESP_LOGI(TAG, "HumitureManager init");
    // 初始化串口型DHT11
    // UART 配置结构体
    uart_config_t uart_config = {
        .baud_rate = BAUD_RATE,             // 波特率
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT
    };

    ESP_ERROR_CHECK(uart_driver_install(UART_PORT_NUM, BUF_SIZE, BUF_SIZE, QUEUE_LENGTH, &uart_queue, 0));
    ESP_ERROR_CHECK(uart_param_config(UART_PORT_NUM, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(UART_PORT_NUM, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));

    uart_enable_pattern_det_baud_intr(UART_PORT_NUM, END_PATTERN, 1, 9, 0, 0);
    uart_pattern_queue_reset(UART_PORT_NUM, 20);

    xTaskCreate(HumitureManager::uart_event_task, "uart_event_task", 4096, this, 10, NULL);

    uart_send_data("Auto\r\n"); //设置为自动模式

    auto& mcp_server = McpServer::GetInstance();
    // 定义设备的属性
    mcp_server.AddTool("self.humiture.temperature", "当前温湿度传感器温度", PropertyList(), [this](const PropertyList&) -> ReturnValue {
        float data = GetCurrentTemperatureData();
        ESP_LOGI(TAG, "当前温度 %f", data);
        return (int)data;
    });

    mcp_server.AddTool("self.humiture.humidity", "当前温湿度传感器湿度", PropertyList(), [this](const PropertyList&) -> ReturnValue {
        float data = GetCurrenthumidityData();
        ESP_LOGI(TAG, "当前湿度 %f", data);
        return (int)data;
    });

    mcp_server.AddTool("self.humiture.temperaturethreshold", "当前温湿度传感器温度阈值", PropertyList(), [this](const PropertyList&) -> ReturnValue {
        float data = GetTemperatureThreshold();
        ESP_LOGI(TAG, "当前温度阈值 %f", data);
        return (int)data;
    });

    mcp_server.AddTool("self.humiture.humiditythreshold", "当前温湿度传感器湿度阈值", PropertyList(), [this](const PropertyList&) -> ReturnValue {
        float data = GetHumidityThreshold();
        ESP_LOGI(TAG, "当前湿度阈值 %f", data);
        return (int)data;
    });


    // 定义设备可以被远程执行的指令
    mcp_server.AddTool("self.humiture.settemperaturethreshold", "设定温湿度传感器温度阈值[注意温度范围]", PropertyList({
        Property("threshold", kPropertyTypeInteger, 0, 100)
    }), [this](const PropertyList& properties) -> ReturnValue {
        float data = properties["threshold"].value<int>();
        ESP_LOGI(TAG, "设定温度阈值为%f", data);
        SetTemperatureThreshold(data);
        return true;
    });

    mcp_server.AddTool("self.humiture.sethumiditythreshold", "设定温湿度传感器湿度阈值[注意湿度范围]", PropertyList({
        Property("threshold", kPropertyTypeInteger, 0, 100)
    }), [this](const PropertyList& properties) -> ReturnValue {
        float data = properties["threshold"].value<int>();
        ESP_LOGI(TAG, "设定湿度阈值为%f", data);
        SetHumidityThreshold(data);
        return true;
    });
}


HumitureManager::~HumitureManager()
{
}

void HumitureManager::uart_send_data(const char* data) {
    // 发送字符串数据
    uart_write_bytes(UART_PORT_NUM, data, strlen(data));
  }

void HumitureManager::process_uart_events()
{
    UBaseType_t watermark = uxTaskGetStackHighWaterMark(NULL);
    ESP_LOGI(TAG, "Task Stack HWM: %u", watermark);
    uart_event_t event;
    uint8_t data[BUF_SIZE] = { 0 };

    while (1) {
        if (xQueueReceive(uart_queue, &event, portMAX_DELAY)) { // 阻塞等待队列事件

            switch (event.type) {
                case UART_DATA:
                {
                    int len = uart_read_bytes(UART_PORT_NUM, data, BUF_SIZE - 1, pdMS_TO_TICKS(100));
                    if (len > 0) {
                        printf("Raw Data task: [%d][", len);
                        for(int i=0; i<len; i++) printf("0x%02X ", data[i]); // 十六进制打印
                        printf("]\n");
                        data[len] = '\0';
                        parse_sensor_data((char*)data); // 调用解析函数
                        // if (m_CurrentTemperatureData > m_TemperatureThreshold) {
                            //     // TODO
                            //     // 让某个LED灯亮或者让小智AI语音提醒你

                            // }

                            // if (m_CurrenthumidityData > m_HumidityThreshold) {
                            //     // TODO
                            //     // 让某个LED灯亮或者让小智AI语音提醒你

                            // }
                    }
                    break;
                }
                case UART_FIFO_OVF:
                    {
                        ESP_LOGI(TAG, "HW FIFO Overflow");
                        uart_flush(UART_PORT_NUM);
                        xQueueReset(uart_queue);
                        break;
                    }
                case UART_BUFFER_FULL:
                    {
                        ESP_LOGI(TAG, "Ring Buffer Full");
                        uart_flush(UART_PORT_NUM);
                        xQueueReset(uart_queue);
                        break;
                    }
                case UART_BREAK:
                    ESP_LOGI(TAG, "Rx Break");
                    break;
                case UART_PARITY_ERR:
                    ESP_LOGI(TAG, "Parity Error");
                    break;
                case UART_FRAME_ERR:
                    ESP_LOGI(TAG, "Frame Error");
                    break;
                case UART_PATTERN_DET:
                    {
                        ESP_LOGI(TAG, "UART_PATTERN_DET warning");
                        unsigned int len = 0;
                        uart_get_buffered_data_len(UART_PORT_NUM, &len);
                        len = uart_read_bytes(UART_PORT_NUM, data, len, pdMS_TO_TICKS(100));
                        if (len > 0) {
                            data[len] = '\0';
                            parse_sensor_data((char*)data);
                        }
                        break;
                    }
                default:
                    ESP_LOGI(TAG, "unknown uart event type: %d", event.type);
                    break;
                }
        }
    }
    vTaskDelete(NULL);
}

void HumitureManager::parse_sensor_data(const char* response)
{
    // 格式示例：R:070.0RH 032.4C\r\n
    float humidity, temperature;
    char* rh_pos = strstr(response, "RH");
    char* c_pos = strstr(response, "C");

    // 校验关键分隔符
    if (!rh_pos || !c_pos || (rh_pos >= c_pos)) {
        ESP_LOGE(TAG, "Invalid format: %s", response);
        return;
    }

    // 提取湿度（R:至RH之间的内容）
    if (sscanf(response, "R:%fRH", &humidity) != 1) {
        ESP_LOGE(TAG, "Humidity parse failed");
        return;
    }

    // 提取温度（RH后的空格至C之间的内容）
    char* temp_start = rh_pos + 2; // 跳过"RH"
    while (*temp_start == ' ') temp_start++; // 跳过多余空格
    if (sscanf(temp_start, "%fC", &temperature) != 1) {
        ESP_LOGE(TAG, "Temperature parse failed");
        return;
    }

    // 数据校验
    if (humidity < 0 || humidity > 100 || temperature < -40 || temperature > 80) {
        ESP_LOGE(TAG, "Data out of range: H=%.1f%%, T=%.1fC", humidity, temperature);
        return;
    }

    m_CurrentTemperatureData = temperature;
    m_CurrenthumidityData = humidity;
    ESP_LOGI(TAG, "Valid Data: %.1f%%, %.1f℃", humidity, temperature);
}